/**
 * Created by jackliu on 17/1/16.
 * 缓存工具，支持：1、缓存到内容（同步）；2、缓存到redis（异步）
 */
var CONFIG = require('../../../../common/config');
var path = require('path');
var fs = require('fs');
var async = require('async');

// 缓存到redis中
var cacheManager = require('cache-manager');
var redisStore = require('cache-manager-redis');
var redisCache = cacheManager.caching({
    store: redisStore,
    host: CONFIG.YJX_JAVA_API_STATICIZE_DOMAIN,
    port: CONFIG.YJX_JAVA_API_STATICIZE_PORT,
    auth_pass: CONFIG.YJX_JAVA_API_STATICIZE_PASSWORD,
    db: CONFIG.YJX_JAVA_API_STATICIZE_DB_NUMBER,
    ttl: CONFIG.YJX_JAVA_API_STATICIZE_TTL
});

/* 对页面进行静态化
 * 目前静态化的数据纪录到内存中，提高访问效率
 */
function staticizeUtil() {
}

/**
 * 将数据记录到redis中(同步)
 *
 * @author 王俊
 * @date 2017-11-29
 *
 * @param uri     接口路由全地址
 * @param para    接口对应参数
 * @param data    需要记录到 redis 中的数据
 * @return {*}    需要记录到 redsi 中的数据
 */
staticizeUtil.recordDataByRedis = function (uri, para, data) {
    var key = staticizeUtil.toKey(uri, para);
    // 下载成功，纪入缓存
    redisCache.set(key, data);
    return data;
};

/**
 * 从redis中获取数据(异步)
 *
 * @author 王俊
 * @date 2017-11-29
 *
 * @param uri          路由全地址, 此为key 前缀
 * @param para         该路由对应的参数
 * @param callback   获取结果的回调
 *          error: 获取缓存数据失败
 *          data: 提取的缓存数据
 */
staticizeUtil.getCacheDataByRedis = function (uri, para, callback) {
    var key = staticizeUtil.toKey(uri, para);
    redisCache.get(key, function (error, data) {
        if (error || !data ) {
            return callback(error || '未获取到缓存数据', null);
        }else {
            // 有缓存就直接返回
            return callback(null, data);
        }
    });
};

/**
 * 获取所有符合条件的缓存 key
 *
 * @author 王俊
 * @date 2017-11-29
 *
 * @param pattern   过滤条件, * 标记所有
 * @param callback  回调
 *          error: 获取失败
 *          keys: 符合条件的 keys
 */
staticizeUtil.getAllPatternCacheKeys = function (pattern, callback) {
    redisCache.keys(pattern, function (error, keys) {
        return callback(error, keys);
    });
};

/**
 * 删除 redis 中指定前缀的所有 key 的缓存
 *
 * @author 王俊
 * @date 2017-11-29
 *
 * @param pattern     要移除 key 的过滤条件, 可为真实 key, 也可为 key 的前缀拼接 *
 * @param callback    回调
 *          error:    清空缓存失败
 */
staticizeUtil.delRedisStaticDataByPattern = function (pattern, callback) {

    staticizeUtil.getAllPatternCacheKeys(pattern, function (getKeysErr, keys) {
        if(getKeysErr) {
            return callback(getKeysErr);
        }
        if(!keys || keys.length === 0) {
            return callback(null)
        }

        staticizeUtil.delRedisStaticDataByKeys(keys, callback);
    });
};

/**
 * 删除给定的缓存 keys 对应的缓存数据
 *
 * @author 王俊
 * @date 2017-11-29
 *
 * @param keys      缓存的确切 key 的数组
 * @param callback  回调
 *          err: 删除失败
 */
staticizeUtil.delRedisStaticDataByKeys = function (keys, callback) {
    var delTasks = [];

    for(var i=0; i<keys.length; i++) {
        var del = (function (redisKey) {
            return function (callback) {staticizeUtil.delRedisStaticDataByKey(redisKey, callback);}
        })(keys[i]);
        if(del) {
            delTasks.push(del);
        }
    }

    async.series(delTasks, function (error) {
        return callback(error);
    });
};

/**
 * 删除 redis 中指定 key 的缓存
 *
 * @author 王俊
 * @date 2017-11-29
 *
 * @param  key      指定删除的 keys, 可带 *
 * @param callback  回调
 *          error: 清空缓存是否成功
 */
staticizeUtil.delRedisStaticDataByKey = function (key, callback) {
    redisCache.del(key, function (error, data) {
        return callback(error, data);
    });
};

/**
 * 清空所有缓存数据
 *
 * @author 王俊
 * @date 2017-11-21
 *
 * @param callback 清空缓存回调
 *          error: 清空失败
 *
 */
staticizeUtil.clearDataByRedis = function (callback) {
    redisCache.reset(callback);
};

/**
 * 根据传入的参数, 转化 redis 缓存的 key
 *
 * @author 王俊
 * @date 2017-11-29
 *
 * @param uri   路由地址全路径, 如: /yjx/v1/document/getTmplDefaultContour_v1_0
 * @param para  该路由对应的参数数据
 * @return {string} 转换后的 redis 标识
 */
staticizeUtil.toKey = function (uri, para) {

    var key = uri + '?';
    if(typeof para === 'string') {
        key += para;
    } else {
        key += JSON.stringify(para || {});
    }
    return key;
};

module.exports = staticizeUtil;